#ifndef _CRT_VAR_H_
#define _CRT_VAR_H_

#include <crt_core.hpp>

#ifdef __cplusplus
extern "C" {
#endif

#pragma pack(push, 1)

enum var_enum_t {
    VET_EMPTY = 0,
    VET_NULL = 1,

    VET_I1 = 2,
    VET_I2 = 3,
    VET_I4 = 4,
    VET_I8 = 5,

    VET_UI1 = 6,
    VET_UI2 = 7,
    VET_UI4 = 8,
    VET_UI8 = 9,

    VET_R4 = 10,
    VET_R8 = 11,

    VET_INT = 12,
    VET_UINT = 13,

    VET_LPSTR = 14,
    VET_LPWSTR = 15,

    VET_VOID = 20

};

/*union {
 *    	CHAR           	VET_I1
 *    	SHORT          	VET_I2
 *    	LONG           	VET_I4
 *	 	LONGLONG       	VET_I8
 *    	BYTE           	VET_UI1
 *    	USHORT         	VET_UI2
 *    	ULONG          	VET_UI4
 *    	ULONGLONG      	VET_UI8
 *    	FLOAT          	VET_R4
 *    	DOUBLE         	VET_R8
 *    	INT            	VET_INT
 *    	UINT           	VET_UINT
 * 		char*			VET_LPSTR
 * 		wchar_t*		VET_LPWSTR
 *	 	void*			VET_VOID
 */

typedef unsigned short var_type;
typedef unsigned short provarv1;
typedef unsigned short provarv2;
typedef unsigned short provarv3;

typedef struct tag_varaint_t {
    var_type vt;
    provarv1 v1;
    provarv2 v2;
    provarv3 v3;
    size_t len;
    union {
        char cVal;   // VET_I1
        short iVal;  // VET_I2
        long lVal;   // VET_I4
        int64 llVal; // VET_I8

        unsigned char uVal;   // VET_UI1
        unsigned short uiVal; // VET_UI2
        unsigned long ulVal;  // VET_UI4
        uint64 ullVal;        // VET_UI8

        float fltVal;  // VET_R4
        double dblVal; // VET_R8

        int intVal;           // VET_INT
        unsigned int uintVal; // VET_UINT

        char* pszVal;            // VET_LPSTR
        unsigned long szVallen;  // VET_LPSTR-->len
        wchar_t* pwszVal;        // VET_LPWSTR
        unsigned long wszVallen; // VET_LPWSTR-->len

        void* pVal; // VET_VOID
    };
} varaint_t;

#pragma pack(pop)

void varaint_t_init(varaint_t* src);
int varaint_t_malloc_string(varaint_t* src, ULONG size, LPCSTR dst);
int varaint_t_malloc_wstring(varaint_t* src, ULONG size, LPCWSTR dst);
int varaint_t_free_string(varaint_t* src);
int varaint_t_copy(varaint_t* src, const varaint_t* dst);
int varaint_t_copystring(varaint_t* src, ULONG size, LPCSTR dst);
int varaint_t_copywstring(varaint_t* src, ULONG size, LPCWSTR dst);

#ifdef __cplusplus
}
#endif

#endif
